import React from 'react';
import {
    ActivityIndicator,
    BackHandler,
    Dimensions,
    StatusBar,
    ToastAndroid,
    InteractionManager,
    Keyboard,
    Platform,
    View,
    TouchableOpacity, DeviceEventEmitter,
} from 'react-native';
import NetworkErrorView from './NetworkErrorView';
import LoadingView from './LoadingView';
import EmptyView from './EmptyView';
import {AlbumView, Overlay, PullPicker, Toast} from 'teaset';
import FadeImage from './FadeImage';
import ToastUtil from 'react-native-cdy-baseui/utils/ToastUtil';

const WIN_WIDTH = Dimensions.get('window').width;
const WIN_HEIGHT = Dimensions.get('window').height;

//
class BasePageV5 extends React.Component {


    constructor(props) {
        super(props);
        this.loadingError = false;
        this.errorMessage = null;
        this.emptyData = null;
        this.loading = true;
        this.first = true;
        this.backButtonShow = false;
        this.backButtonTintColor = null;
        this.loadData = this.loadData.bind(this);
        this.firstWillFocus = true;
        this.customKey = null;
        this.keyboardVisible = false;
        this.keyboardHeight = 0;
    }

    showDismissViewWhenKeyboardUp(){
        return false;
    }

    printState() {
        console.log(this.state);
    }

    getKeyboardHeight(){
        return this.keyboardHeight;
    }

    registerListener = () => {
        const {navigation} = this.props;
        if (navigation) {
            this.focusListener = navigation.addListener('focus', () => {
                // The screen is focused
                // Call any action
                if (this.first) {
                    this.first = false;
                    this.didFocus(true);
                } else {
                    this.didFocus(false);
                }
                if (this.alertExitMessage() && Platform.OS === 'android') {
                    BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
                }
            });
            this.blurListener = navigation.addListener('blur', () => {
                this.didBlur();
                if (Platform.OS === 'android' && this.alertExitMessage()) {
                    BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
                }
            });
            this.willBlurListener = navigation.addListener('beforeRemove', (e) => {
                console.log('beforeRemove');
                this.beforeRemove(e);
            });
        }
    };

    androidBackAction() {

        return false;
    }

    shouldReplaceDefaultAndroidBackAction() {
        return false;
    }

    onBackAndroid = () => {
        if (this.androidBackAction()) {
            return this.shouldReplaceDefaultAndroidBackAction();//默认行为
        }
        if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
            //最近2秒内按过back键，可以退出应用。
            BackHandler.exitApp();
            return false;
        }
        this.lastBackPressed = Date.now();
        ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT);
        return true;//默认行为
    };

    beforeRemove(e) {

    }

    didFocus(first) {

    }

    didBlur(){

    }

    componentWillUnmount() {
        this.unregisterListener();
        if (Platform.OS === 'android' && this.alertExitMessage()) {
            BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
        }
        this.willUnmount();
    }

    willUnmount() {
        this.keyboardEventListeners && this.keyboardEventListeners.forEach((eventListener) => eventListener.remove());
    };


    componentDidMount() {
        this.registerListener();
        this.didMount();
    }

    alertExitMessage() {
        return false;
    }

    didMount() {
        if (Platform.OS === 'ios') {
            this.keyboardEventListeners = [
                Keyboard.addListener('keyboardWillShow', this._onKeyboardWillShow),
                Keyboard.addListener('keyboardWillHide', this._onKeyboardWillHide),
            ];
        } else {
            this.keyboardEventListeners = [
                Keyboard.addListener('keyboardDidShow', this._onKeyboardWillShow),
                Keyboard.addListener('keyboardDidHide', this._onKeyboardWillHide),
            ];
        }
        InteractionManager.runAfterInteractions(() => {
            this.loadData();
        });
    };


    _onKeyboardWillShow = (event)=>{
        this.keyboardVisible = true;
        this.keyboardHeight = event.endCoordinates.height;
        this.keyBoardWillShow();
        this.forceUpdate();
    }

    keyBoardWillShow(){

    }

    _onKeyboardWillHide = ()=>{
        this.keyboardVisible =false;
        this.keyboardHeight = 0;
        Keyboard.dismiss();
        this.keyBoardWillHide();
        this.forceUpdate();
    }

    keyBoardWillHide(){

    }

    setTitle(title) {
        this.props.navigation.setOptions({
            title: title
        });
    }

    setTitleView(titleView, headerRight) {
        this.props.navigation.setOptions({
            headerTitle: titleView,
            headerRight: headerRight
        });
    }

    setTitleRight(headerRight) {
        this.props.navigation.setOptions({
            headerRight: headerRight
        });
    }

    unregisterListener = () => {
        this.focusListener && this.focusListener();
        this.focusListener = null;
        this.blurListener && this.blurListener();
        this.blurListener = null;
        this.willBlurListener && this.willBlurListener();
        this.willBlurListener = null;
    };


    showPage(name, params = null) {
        this.props.navigation.push(name, params);
    }

    async loadData() {
        if (this.fetchRemoteData) {
            try {
                const data = await this.fetchRemoteData(()=>{
                    this.hideLoading(true);
                });
            }catch (e) {
                this.showErrorMessage(e.message);
            }
        }
        else {
            this.hideLoading();
        }
    };

    fetchRemoteData = null;

    showLoadingError = () => {
        this.loadingError = true;
        this.forceUpdate();
    };

    showBackButotn(tintColor) {
        this.backButtonShow = true;
        this.backButtonTintColor = tintColor;
    }

    hideBackButton() {
        this.backButtonShow = false;
    }

    showErrorMessage = (message) => {
        this.loadingError = true;
        this.errorMessage = message;
        this.forceUpdate();
    };

    showEmptyView = (emptyText) => {
        this.loading = false;
        this.loadingError = false;
        this.emptyData = emptyText;
        this.forceUpdate();
    };

    showLoading = () => {
        this.loading = true;
        this.loadingError = false;
        this.forceUpdate();
    };

    showHud(text) {
        if (text) {
            if (this.customKey) {
                Toast.hide(this.customKey);
            }
            this.customKey = Toast.show({
                    icon: <ActivityIndicator size='large' color={'white'}/>,
                    position: 'center',
                    duration: 1000000,
                    modal: true,
                    text,
                },
            );
        }
    }

    hideHud() {
        if (this.customKey) {
            Toast.hide(this.customKey);
        }
    }

    hideLoading = (force = true) => {
        this.loading = false;
        this.loadingError = false;
        //LayoutAnimation.spring();
        if (force) {
            this.forceUpdate();
        }
    };

    // Navigation
    pushPage(name, params) {
        this.props.navigation.push(name, params);
    }

    navigatePage(name, params) {
        this.props.navigation.navigate(name, params);
    }

    replacePage(name, params) {
        this.props.navigation.replace(name, params);
    }

    dismissPage(){
        this.props.navigation.getParent() && this.props.navigation.getParent().pop();
    }

    getParam(name, fallback) {
        return (this.props.route.params && this.props.route.params[name]) || fallback;
    }

    setParams(params){
        this.props.navigation.setParams(params);
    }

    pop() {
        this.props.navigation.pop();
    }

    popToTop() {
        this.props.navigation.popToTop();
    }

    executeCompetion(data) {
        return this.executeCompletion(data);
    }
    executeCompletion(data, updateUI=true) {
        const completion = this.getParam('completion');
        if (completion) {
            if (updateUI) {
                requestAnimationFrame(()=>{
                    completion(data, this);
                });
            }
            else {
                completion(data, this);
            }
            return true;
        }
        return false;
    }

    showSelectItems(title, items, selectedIndex, onSelected) {
        PullPicker.show(
            title,
            items,
            selectedIndex,
            onSelected,
        );
    }

    renderContent() {

    };

    previewImages(images) {
        if (images.length === 0) {
            return;
        }
        let overlayView = (
            <Overlay.PopView
                style={{}}
                containerStyle={{flex: 1}}
                overlayOpacity={1}
                type='custom'
                customBounds={{x: WIN_WIDTH / 2, y: WIN_HEIGHT / 2, width: 0, height: 0}}
                ref={v => this.fullImageView = v}
            >
                <AlbumView
                    style={{flex: 1}}
                    control={true}
                    images={images.map(value => {
                        return <FadeImage defaultSource={null}
                                          showLoading={true}
                                          source={{uri: value}}
                                          resizeMode={'contain'}
                                          style={{width: WIN_WIDTH, height: WIN_HEIGHT}}
                                          backgroundColor={'transparent'}/>;
                    })}
                    defaultIndex={0}
                    onPress={() => this.fullImageView && this.fullImageView.close()}
                />
                <StatusBar animated={false} hidden={true}/>
            </Overlay.PopView>
        );
        Overlay.show(overlayView);
    };

    render() {
        const errorView = <NetworkErrorView errorInfo={this.errorMessage} onPress={() => {
            this.showLoading();
            this.loadData();
        }}
                                            showBackButton={this.backButtonShow}
                                            backButtonTintColor={this.backButtonTintColor}/>;

        const loadingView = <LoadingView animating={this.loading}/>;

        const emptyView = <EmptyView emptyText={this.emptyData} onPress={() => this.onEmptyViewPressed()}/>;

        if (this.loadingError) {
            return this.renderErrorView(errorView);
        }
        if (this.loading) {
            return this.renderLoadingView(loadingView);
        }
        if (this.emptyData) {
            return this.renderEmptyView(emptyView);
        }
        return <View style={{flex: 1, width:'100%', alignItems:'stretch'}} onLayout={(e) => {
            this.viewHeight = e.nativeEvent.layout.height;
        }}>
            {this.renderContent()}
            {this.keyboardVisible && this.showDismissViewWhenKeyboardUp() ? <View style={{position:'absolute', top:0, left:0, right:0, height:( this.viewHeight || WIN_HEIGHT) - ((this.keyboardHeight || 150) + this.getInputViewHeight()), zIndex:9999}}>
                <TouchableOpacity style={{flex: 1, width:'100%'}} onPress={this.dismissAllView}><View style={{flex: 1, width:'100%' }}/></TouchableOpacity>
            </View>: null}
        </View>;
    }
    isKeyboardVisible(){
        return this.keyboardVisible;
    }

    dismissAllView = ()=>{
        Keyboard.dismiss();
        DeviceEventEmitter.emit(BasePageV5.DISMISS_KEYBOARD);
    }

    getInputViewHeight(){
        return 55;
    }

    static DISMISS_KEYBOARD = 'DISMISS_KEYBOARD';

    onEmptyViewPressed() {

    }

    renderErrorView(errorView) {
        return errorView;
    }

    renderLoadingView(loadingView) {
        return loadingView;
    }

    renderEmptyView(emptyView) {
        return emptyView;
    }
}

export default BasePageV5;
